package com.agou.core.ss;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Vector;

import com.agou.core.util.UtFormat;

/**
 * 运行时异常
 * 
 * @author Administrator
 * 
 */
public abstract class SSRuntimeException extends RuntimeException implements
		java.io.Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 2064035978861739859L;
	private String _exType;// 异常类型
	private int _exCode = -1;// 错误码
	private String _exMsg = null;// 异常信息
	// 存放详细的补充信息,此属性在缺省方式下不填，需要时通过addDetail(String strDetailMessage)方法补充
	private Vector<String> _vectorDetail = null;
	// private String _className = null;//抛出异常的类名
	// private String _methodName = null;//抛出异常的方法名
	// 调用栈, 当截获系统异常而需要转换为SSException时, 用此栈存放原异常的调用情况, 以利于查错
	private StringBuffer _callStack = null;
	// 源异常, 即导致当前异常发生的原始异常
	private SSThrowable _origin = null;

	/**
	 * 异常的构造函数, 用于子类填写相关信息
	 * 
	 */
	protected SSRuntimeException(String strExType, int nExCode, String sExStr,	Object... args) {
		this._exType = strExType;// 异常类型
		this._exCode = nExCode;// 异常代码
		this._exMsg = sExStr;// 异常信息
		this._vectorDetail = null;
		if (args.length > 0) {
			this._exMsg = UtFormat.format(sExStr, args);// LoggerUtils.format(sExStr,
														// args) ;// 异常信息
		} else {
			this._exMsg = sExStr;// 异常信息
		}
		// this._className = className;//类名
		// this._methodName = methodName;//方法名称
	}

	/**
	 * 异常的构造函数, 用于子类填写相关信息
	 * 
	 */
	protected SSRuntimeException(String strExType, int nExCode, String sExStr,	Throwable e, String... args) {
		this(strExType, nExCode, sExStr);
		this._origin = new SSThrowable(e);
	}

	/**
	 * 为异常补充更加详细的错误信息
	 * 
	 * @param detailMessage
	 *            错误的详细说明信息
	 */
	public final void addDetail(String detailMessage, Object... args) {
		if (_vectorDetail == null) {
			_vectorDetail = new Vector<String>();
		}
		if (args.length > 0) {
			_vectorDetail.add(UtFormat.format(detailMessage, args));// SSTrace.format(sExStr,
																	// args);
		} else {
			_vectorDetail.add(detailMessage);
		}
		// _vectorDetail.addElement(detailMessage);
	}

	/**
	 * 存入捕获到异常时的调用栈
	 * 
	 * @param e
	 *            异常
	 * @throws IOException
	 */
	public final void saveStackTrace(Throwable e) throws IOException {
		if (this._callStack == null) {
			this._callStack = new StringBuffer();
		}
		ByteArrayOutputStream osCallStack = new ByteArrayOutputStream();
		PrintWriter pw = new PrintWriter(osCallStack);
		pw.print(' ');
		e.printStackTrace(pw);
		pw.flush();
		pw.close();
		this._callStack.append(osCallStack.toString());
		osCallStack.close();
		return;
	}

	/**
	 * 是否有捕获到异常时的调用栈
	 * 
	 * @return
	 */
	public final boolean hasStackTrace() {
		if (this._callStack != null) {
			return true;
		}
		return false;
	}

	/**
	 * 取得错误的完整说明信息
	 * 
	 * @return 错误信息
	 */
	public String getMessage() {
		String errorInfo = _exType + ", " + _exCode + ", " + _exMsg + ", " + _vectorDetail;
		return errorInfo;
	}

	/**
	 * 取得异常类型
	 * 
	 * @return 异常类型
	 */
	public String getExType() {
		return _exType;
	}

	/**
	 * 取得错误代码
	 * 
	 * @return 错误码
	 */
	public int getExCode() {
		return _exCode;
	}

	/**
	 * 取得错误信息
	 * 
	 * @return 错误信息
	 */
	public String getExMessage() {
		return _exMsg;
	}

	/**
	 * 取得错误补充信息
	 * 
	 * @return 错误详细信息
	 */
	public String getDetail() {
		if (_vectorDetail == null) {
			return "";
		}
		String strDetail = null;
		for (int i = 0; i < _vectorDetail.size(); i++) {
			if (strDetail == null) {
				strDetail = (String) _vectorDetail.elementAt(i);
			} else {
				strDetail += "; " + (String) _vectorDetail.elementAt(i);
			}
		}
		return strDetail;
	}

	/**
	 * 将异常或错误中的调用栈以字符串形式倒出
	 * 
	 * @param e
	 *            异常或错误
	 * @return 字符串形式的调用栈
	 */
	public static String getStringFromStream(Throwable e) {

		ByteArrayOutputStream osCallStack = new ByteArrayOutputStream();
		PrintWriter pw = new PrintWriter(osCallStack);
		e.printStackTrace(pw);
		pw.flush();
		pw.close();
		return osCallStack.toString();
	}

	/**
	 * 取导致当前异常发生的原始异常或错误
	 * 
	 * @return 原始异常或错误
	 */
	public SSThrowable getOrigin() {
		return _origin;
	}

	// public Document getXmlDocument() {
	// return xmlDoc;
	// }
	//
	//
	// /**
	// * 取得XML异常表达
	// * @param enCode
	// * @return
	// */
	// public String getXmlMsg(String enCode) {
	// createXml(enCode);
	// return this.getXmlString();
	// }
	//
	//
	//
	// /** XML节点-异常 */
	// public final static String xmlNTagException = "exception";
	// /** XML属性-类名 */
	// public final static String xmlNTagExceptionClassName = "className";
	// /** XML属性-类名 */
	// public final static String xmlNTagExceptionMethodName = "methodName";
	// /** XML属性-类名 */
	// public final static String xmlNTagExceptionErrorCode = "errorCode";
	// /** XML属性-类名 */
	// public final static String xmlNTagExceptionDetail = "detail";
	// /** XML属性-错误类型*/
	// public final static String xmlNTagExceptionType = "type";
	// /** XML属性-类名 */
	// public final static String xmlNTagExceptionMessage = "message";
	// /** XML属性-类名 */
	// public final static String xmlNTagExceptionExMessage = "exMessage";
	// /** XML属性-类名 */
	// public final static String xmlNTagExceptionFromStream = "stack";
	// //XML标记 - XML版本
	// private static String xmlVersion = "1.0";
	// //XML标记 - 字符集
	// private static String xmlEncoding = "GB2312";
	// //XML文档对象
	// private Document xmlDoc = null;
	// //保存XML字符串
	// private String strXml = null;
	//
	// /**
	// * 建立XML对象
	// * @throws ParserConfigurationException
	// * @throws IOException
	// * @throws SSException
	// */
	// private void createXml(String enCode) {
	// xmlEncoding = enCode;
	// try {
	// //产生XML文档对象
	// this.generateXMLDocument();
	// //产生XML字符串
	// this.generateXMLString();
	// } catch (ParserConfigurationException e) {
	// throw new java.lang.IllegalArgumentException("解析XML配置错误！");
	// } catch (IOException e) {
	// throw new java.lang.IllegalArgumentException("解析XML输入输出错误！");
	// }
	//
	// }
	//
	// /**
	// * 产生XML文档
	// * @throws ParserConfigurationException
	// * @throws IOException
	// * @throws SSException
	// */
	// private void generateXMLDocument() throws ParserConfigurationException,
	// IOException {
	// //产生一个DocumentBuilder工厂的实例
	// DocumentBuilderFactory dbFactory =
	// DocumentBuilderFactoryImpl.newInstance();
	// //通过DocumnetBuilder工厂产生一个DoucmentBuilder
	// DocumentBuilder docBuilder = dbFactory.newDocumentBuilder();
	// //产生文档对象
	// xmlDoc = docBuilder.newDocument();
	// //定义元素对象
	// Element root;
	// //建立根元素
	// root = xmlDoc.createElement(xmlNTagException);
	// //添加字段元素
	// xmlFill(xmlDoc, root);
	// xmlDoc.appendChild(root);
	// }
	//
	// /**
	// * 填充字段信息
	// * @param xmlDoc - XML文档
	// * @param root - 根据元素
	// * @throws ParserConfigurationException
	// * @throws IOException
	// * @throws SSException
	// */
	// private void xmlFill(Document xmlDoc, Element root) throws
	// ParserConfigurationException, IOException {
	// Element rootRtem;
	// rootRtem = xmlDoc.createElement(xmlNTagExceptionClassName);
	// rootRtem.appendChild(xmlDoc.createTextNode(getClassName()));
	// root.appendChild(rootRtem);
	// //方法xmlNTagExceptionType
	// rootRtem = xmlDoc.createElement(xmlNTagExceptionMethodName);
	// rootRtem.appendChild(xmlDoc.createTextNode(getMethodName()));
	// root.appendChild(rootRtem);
	//
	// //方法
	// rootRtem = xmlDoc.createElement(xmlNTagExceptionType);
	// rootRtem.appendChild(xmlDoc.createTextNode(this.getExType()));
	// root.appendChild(rootRtem);
	// //错误吗
	// rootRtem = xmlDoc.createElement(xmlNTagExceptionErrorCode);
	// rootRtem.appendChild(xmlDoc.createTextNode(String.valueOf(getExCode())));
	// root.appendChild(rootRtem);
	// //附加信息
	// rootRtem = xmlDoc.createElement(xmlNTagExceptionDetail);
	// rootRtem.appendChild(xmlDoc.createTextNode(getDetail()));
	// root.appendChild(rootRtem);
	// //详细信息
	// rootRtem = xmlDoc.createElement(xmlNTagExceptionMessage);
	// rootRtem.appendChild(xmlDoc.createTextNode(getMessage()));
	// root.appendChild(rootRtem);
	// //错误信息
	// rootRtem = xmlDoc.createElement(xmlNTagExceptionExMessage);
	// rootRtem.appendChild(xmlDoc.createTextNode(getExMessage()));
	// root.appendChild(rootRtem);
	// //堆栈
	// rootRtem = xmlDoc.createElement(xmlNTagExceptionFromStream);
	// rootRtem.appendChild(xmlDoc.createTextNode(getStringFromStream(this)));
	// root.appendChild(rootRtem);
	//
	// }
	//
	// /**
	// * 取得XML字符串
	// * @throws ParserConfigurationException
	// * @throws IOException
	// * @throws SSException
	// */
	// private void generateXMLString() throws ParserConfigurationException,
	// IOException {
	// StringWriter strWriter = null;
	// XMLSerializer probeMsgSerializer = null;
	// OutputFormat outFormat = null;
	// probeMsgSerializer = new XMLSerializer();
	// strWriter = new StringWriter();
	// outFormat = new OutputFormat();
	// // Setup format settings
	// outFormat.setEncoding(xmlEncoding);
	// outFormat.setVersion(xmlVersion);
	// outFormat.setIndenting(true);
	// outFormat.setIndent(4);
	// //Define a Writer
	// probeMsgSerializer.setOutputCharStream(strWriter);
	// //Apply the format settings
	// probeMsgSerializer.setOutputFormat(outFormat);
	// //Serialize XML Document
	// probeMsgSerializer.serialize(xmlDoc);
	// this.strXml = strWriter.toString();
	// strWriter.close();
	// }
	//
	// /**
	// * 取得XML字符串
	// * @return
	// */
	// private String getXmlString() {
	// return strXml;
	// }

}
